import React from 'react';
import {
  SVGOverlay,
  withLeaflet
} from 'react-leaflet';
import { isEqual } from 'lodash';
import PathFactory from '../utils/PathFactory';
import styles from './Geojson.less';
import {
  defines,
  createOutlines,
  hightlightLabel
} from '../utils/marker';
import {
  getAreaColor,
  colcWHPercentage
} from '../utils/util';

class Geojoson extends React.Component {
  constructor(props) {
    super(props);
    const { geoJsonData } = props;
    this.randomNumber = Math.floor(Math.random() * 10000);
    this.state = {
      activeRegion: 0,
      cityPath: ''
    };
    this.svgInfo = {
      uuid: this.randomNumber,
      cityPath: '',
      rectangle: PathFactory.getBound(geoJsonData)
    };
    this.wh = {
      width: 0,
      height: 0
    };
  }

  svgOverlayRef=(event) => {
    if (!event) return;
    const w = event.container.clientWidth;
    const h = event.container.clientHeight;
    const { wp, hp } = colcWHPercentage(w, h);
    const baseNumber = 1500;
    this.wh = {
      width: Math.floor(baseNumber * wp),
      height: Math.floor(baseNumber * hp)
    };
    this.resetGeojson();
  }

  shouldComponentUpdate(nextProps) {
    const { geoJsonData } = this.props;
    const { geoJsonData: nextGJD } = nextProps;
    if (!isEqual(geoJsonData, nextGJD)) {
      this.svgInfo.rectangle = PathFactory.getBound(nextGJD);
      this.randomNumber = Math.floor(Math.random() * 10000);
    }
    return true;
  }

  resetGeojson() {
    try {
      const { geoJsonData } = this.props;
      const { width, height } = this.wh;
      const pathFactory = new PathFactory({
        width, height, geojson: geoJsonData
      });
      this.geoData = pathFactory.getPaths() || [];
      this.setState({ cityPath: pathFactory.getCityPath() });
    } catch (e) {
      // eslint-disable-next-line no-console
      console.error('GeoDimensional geojson 解析失败', e);
    }
  }

  setActiveRegion(id) {
    const { activeRegion } = this.state;
    if (id !== activeRegion) {
      this.setState({ activeRegion: id });
    }
  }

  get common() {
    const { config: { common } } = this.props;
    return common;
  }

  get area() {
    const { config: { area } } = this.props;
    return area;
  }

  // 选中时的dom
  renderLightPath = (regions) => {
    if (!regions) return null;
    const { activeRegion } = this.state;
    const feature = regions.find(item => item.id === activeRegion);
    if (!feature) return null;
    const { value, path, name } = feature;
    const { areaColors } = this.area;
    const { activeFont } = this.common;
    const { uuid } = this.svgInfo;
    const color = getAreaColor(value, areaColors);
    return (
      <g className={styles.light}>
        {createOutlines({
          color, path, name, uuid
        })}
        {hightlightLabel(feature, activeFont)}
      </g>
    );
  }

  // 默认展示的dom
  renderRegion = ({ id, path }) => {
    const { backgroundInnerColor } = this.common;
    const { borderWidth, borderColor } = this.area;
    const { uuid } = this.svgInfo;
    return (
      <g
        key={`${id}_${uuid}`}
        className={styles.region}
      >
        <path
          d={path}
          style={{
            strokeWidth: borderWidth,
            stroke: borderColor,
            fill: backgroundInnerColor
          }}
        ></path>
      </g>
    );
  }

  render() {
    const { width, height } = this.wh;
    const {
      backgroundColor, outlineColor,
    } = this.common;
    const { areaColors } = this.area;
    const { rectangle, uuid } = this.svgInfo;
    const { cityPath } = this.state;
    const regions = this.geoData || [];
    return (
      <SVGOverlay
        key={this.randomNumber}
        ref={this.svgOverlayRef}
        bounds={rectangle}
        viewBox={`${0} ${0} ${width} ${height}`}
      >
        {areaColors.map(
          ({ color }, idx) => defines({
            id: `${color}_${idx}_${uuid}`, rect: color
          })
        )}
        <defs>
          <filter>
            <feDropShadow
              dx="0"
              dy="16"
              stdDeviation="16"
              floodColor="black"
            />
          </filter>
          <path id={`city-path_${uuid}`} d={cityPath}></path>
        </defs>
        <use
          transform="translate(0, 12)"
          xlinkHref={`#city-path_${uuid}`}
          fill={outlineColor}
        />
        <g>
          <use
            xlinkHref={`#city-path_${uuid}`}
            stroke={backgroundColor}
            strokeWidth="5"
            fill="none"
          ></use>
        </g>
        <g className={styles.top}>
          {regions.map(this.renderRegion)}
        </g>
        {this.renderLightPath(regions)}
      </SVGOverlay>
    );
  }
}

export default withLeaflet(Geojoson);
